package com.ruoyi.media.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dtflys.forest.http.ForestCookie;
import com.ruoyi.common.utils.StringUtils;
//import sun.misc.BASE64Decoder;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.util.*;

public class WxUtils {

    /**
     * 处理cookies并返回请求接口cookies
     * @param cookies
     * @return
     */
    public static String resetCookies(String cookies){
        JSONArray jo =  JSONArray.parseArray(cookies);
        String valStr = ""; //返回结果集
        for(int i = 0; i<jo.size() ; i++){
            JSONObject itemJo = (JSONObject)jo.get(i);
            for(Map.Entry<String,Object> entry : itemJo.entrySet() ){
                if(entry.getKey().equals("name")){
                    valStr += entry.getValue();
                }
                if(entry.getKey().equals("value")){
                    valStr +=  "=" +  entry.getValue() + "; ";
                }
            }
        }
        return valStr;
    }


    /**
     * 根据base64字符串获取html数据
     * @param deCodeData
     * @return
     */
//    public static String deCodeBase64Data(String deCodeData) throws IOException {
//        final BASE64Decoder decoder = new BASE64Decoder();
//        return new String(decoder.decodeBuffer(deCodeData));
//    }


    /**
     * 获取图片的inputstream
     * @param imageUrl
     * @return
     * @throws IOException
     */
    public static InputStream getImageInputStream(String imageUrl) throws IOException {
        URL url = new URL(imageUrl);
        URLConnection connection = url.openConnection();
        connection.connect();
        return connection.getInputStream();
    }



    public static Map<String,String> cookiesPutMap(String cookies){
        JSONArray jsonArray =  JSONArray.parseArray(cookies);
        Map<String,String> cookieMap = new HashMap<>();
        for(int i = 0; i<jsonArray.size() ; i++){
            JSONObject itemJo = (JSONObject)jsonArray.get(i);
            String name = itemJo.getString("name");
            String value = itemJo.getString("value");
            cookieMap.put(name,value);
        }
        return cookieMap;
    }




    /**
     * 将十位的时间戳转换为YYYYMMdd格式的时间字符串
     * @param timeStamp
     * @return
     */
    public static String timeStampToStr(String timeStamp){
        SimpleDateFormat tempType = new SimpleDateFormat("yyyyMMdd");  //定义时间类型
        Long timeNum =  Long.parseLong(timeStamp) * 1000;
        Timestamp tempTime = new Timestamp(timeNum);
        return  tempType.format(tempTime);
    }



    /**
     * 获取昨天的日期
     * @return
     */
    public static  String getYesterday(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(new Date());
        calendar.add(calendar.DATE,-1);
        String date2 = sdf.format(calendar.getTime());
        return date2;
    }


    /**
     * 根据路径识别图片是否二维码
     * @param path
     * @return
     */
//    public static String deEncodeByPath(String path) {
//        String content = null;
//        BufferedImage image;
//        try {
//            URL url= new URL(path);
//            image = ImageIO.read(url);
//            LuminanceSource source = new BufferedImageLuminanceSource(image);
//            Binarizer binarizer = new HybridBinarizer(source);
//            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
//            Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
//            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
//            Result result = new MultiFormatReader().decode(binaryBitmap, hints);//解码
//            System.out.println("图片中内容：  ");
//            System.out.println("content： " + result.getText());
//            content = result.getText();
//        } catch (IOException e) {
//            e.printStackTrace();
//        } catch (NotFoundException e) {
//            //这里判断如果识别不了带LOGO的图片，重新添加上一个属性
//            try {
//                image = ImageIO.read(new File(path));
//                LuminanceSource source = new BufferedImageLuminanceSource(image);
//                Binarizer binarizer = new HybridBinarizer(source);
//                BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
//                Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
//                //设置编码格式
//                hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
//                //设置优化精度
//                hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
//                //设置复杂模式开启（我使用这种方式就可以识别微信的二维码了）
//                hints.put(DecodeHintType.PURE_BARCODE,Boolean.TYPE);
//                Result result = new MultiFormatReader().decode(binaryBitmap, hints);//解码
//                System.out.println("图片中内容：  ");
//                System.out.println("content： " + result.getText());
//                content = result.getText();
//            } catch (IOException as) {
//                as.printStackTrace();
//            } catch (NotFoundException as) {
//                as.printStackTrace();
//            }
//        }
//        return content;
//    }



    /**
     * 获取过去第几天的日期
     *
     * @param past
     * @return
     */
    public static String getPastDate(int past,Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - past);
        Date today = calendar.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String result = sdf.format(today);
        return result;
    }



    /**
     * 通过hashset特性获取随机不重复的值
     * @param min
     * @param max
     * @param n
     * @param set
     */
    public static void randomSet(int min, int max, int n, HashSet<Integer> set) {
          if (n > (max - min + 1) || max < min) {
               return;
          }
          for (int i = 0; i < n; i++) {
                  // 调用Math.random()方法
                   int num = (int) (Math.random() * (max - min)) + min;
                   set.add(num);// 将不同的数存入HashSet中
              }
            int setSize = set.size();
           // 如果存入的数小于指定生成的个数，则调用递归再生成剩余个数的随机数，如此循环，直到达到指定大小
          if (setSize < n) {
                  randomSet(min, max, n - setSize, set);// 递归
              }
       }



    /**
     * 生成随机32位的小写加数字
     * @return
     */
    public static  String getLower32(){
        String seq = "";
        String str = "abcdefghijklmnopqrstuvwxyz0123456789";
        for(int i = 0; i < 32 ;i++){
            seq += str.charAt((int) Math.floor(Math.random() * str.length()));
        }
        return seq;
    }




    /**
     * 随机生成的随机字符
     * @return
     */
    public static  String getRandomStr(int length){
        String seq = "";
        String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        for(int i = 0; i < length ;i++){
            seq += str.charAt((int) Math.floor(Math.random() * str.length()));
        }
        return seq;
    }

    /**
     * 随机生成 随机数
     * @return
     */
    public static  String getRandomNumber(int length){
        String seq = "";
        String str = "0123456789";
        for(int i = 0; i < length ;i++){
            seq += str.charAt((int) Math.floor(Math.random() * str.length()));
        }
        return seq;
    }

    /**
     * 根据当前时间戳生成32位随机数
     * @return
     */
    public static  String getRandomNumberByTime(){
        String seq = "";
        String str = "0123456789";
        for(int i = 0; i < 5 ;i++){
            seq += str.charAt((int) Math.floor(Math.random() * str.length()));
        }
        return System.currentTimeMillis() + seq;
    }




    /**
     * 设置每个文件的切片大小
     * @param fileSize
     * @return
     */
    public static List<Integer> getChannelsSize(long fileSize,int size){
        List<Integer> resSize = new ArrayList<>();
        int uploadSize = 1024 * 1024 * size; //单次上传文件的大小
        Long headNum = Math.round( (double) (fileSize / uploadSize)); //前面的文件数量 向下取整
        if(headNum == 0){ //说明只能分割为一个大小
            resSize.add(Integer.parseInt(String.valueOf(fileSize)));
        }else{
            int countSize = 0;
            for(int i = 0 ; i < headNum ; i++){  //根据文件大小处理
                countSize += uploadSize;
                resSize.add(countSize);
            }
            if(fileSize != countSize){
                resSize.add(Integer.parseInt(String.valueOf(fileSize)));
            }
        }
        return resSize;
    }


    /**
     * 获取本机的Mac地址
     * @return
     */
    public static String getMac() {
        InetAddress ia;
        byte[] mac = null;
        try {
            // 获取本地IP对象
            ia = InetAddress.getLocalHost();
            // 获得网络接口对象（即网卡），并得到mac地址，mac地址存在于一个byte数组中。
            mac = NetworkInterface.getByInetAddress(ia).getHardwareAddress();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 下面代码是把mac地址拼装成String
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < mac.length; i++) {
            if (i != 0) {
                sb.append("-");
            }
            // mac[i] & 0xFF 是为了把byte转化为正整数
            String s = Integer.toHexString(mac[i] & 0xFF);
            sb.append(s.length() == 1 ? 0 + s : s);
        }
        // 把字符串所有小写字母改为大写成为正规的mac地址并返回
        return sb.toString().toUpperCase();
    }


    /**
     * 校验返回参数
     * @return
     */
    public static Boolean checkRes(String response){
        boolean flag = false;
        if(StringUtils.isNotEmpty(response)){
            JSONObject res =  JSONObject.parseObject(response);
            if(res.getJSONObject("base_resp").getInteger("ret") == 0){
                flag = true;
            }
        }
        return flag;
    }



    /**
     * 传入一个json字符串cookies集合
     * 返回一个可用的cookies集合
     * @return
     */
    public static List<ForestCookie> resetForestCookie(String cookiesJsonStr){
        List<ForestCookie> cookiesList = new ArrayList<>();
        JSONArray jsonArray = JSONArray.parseArray(cookiesJsonStr);
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            String name = jsonObject.getString("name");
            String value = jsonObject.getString("value");
            String domain = jsonObject.getString("domain");
            String path = jsonObject.getString("path");
            Date expires = jsonObject.getDate("expires");
            boolean httpOnly = jsonObject.getBoolean("httpOnly");
            boolean secure = jsonObject.getBoolean("secure");
            Date createTime = new Date();
            Duration maxAge = Duration.parse(jsonObject.getString("maxAge"));
            cookiesList.add(new ForestCookie(name, value, createTime, maxAge, domain, path, secure, httpOnly, true, true));
        }
        return cookiesList;
    }

    /**
     * 传入一个字符串类型的cookies并格式化
     * 返回一个可用的cookies集合
     * @return
     */
    public static List<ForestCookie> resetForestCookieByStr(String cookiesStr){
        List<String> cookies = Arrays.asList(cookiesStr.split(";"));
        List<ForestCookie> forestCookies = new ArrayList<>();
        if(cookies.size() > 0){
            for(int i = 0;i < cookies.size();i++){
                String realCookies = cookies.get(i).replace("\n","");
                String[]  cookie = realCookies.split("=");
                ForestCookie forestCookie = new ForestCookie(cookie[0],cookie[1]);
                forestCookies.add(forestCookie);
            }
            return forestCookies;
        }
        return null;
    }



    /**
     * 获取当天时间开始和结束的时间戳
     * @return startTime  endTime
     */
    public static Map<String,Object> queryStartAndEndTime(){
        Map<String,Object> timeMap = new HashMap<>();
        Calendar startTime = Calendar.getInstance();
        Calendar endTime = Calendar.getInstance();
        startTime.set(Calendar.HOUR_OF_DAY, 0);
        startTime.set(Calendar.MINUTE, 0);
        startTime.set(Calendar.SECOND, 0);
        startTime.set(Calendar.MILLISECOND, 0);
        endTime.set(Calendar.HOUR_OF_DAY, 24);
        endTime.set(Calendar.MINUTE, 0);
        endTime.set(Calendar.SECOND, 0);
        endTime.set(Calendar.MILLISECOND, 0);
        Long weeHours = startTime.getTimeInMillis()/1000; //当天凌晨的十位时间戳
        Long maxHours = endTime.getTimeInMillis()/1000; //当天晚上的十位时间戳
        timeMap.put("startTime",weeHours.toString());
        timeMap.put("endTime",maxHours.toString());
        return timeMap;
    }



    /**
     * 通过链接下载视频
     * @param httpUrl
     * @param saveFile
     * @return
     */
    public static boolean httpDownload(String httpUrl, String saveFile) {
        // 1.下载网络文件
        int byteRead;
        URL url;
        try {
            url = new URL(httpUrl);
        } catch (MalformedURLException e1) {
            e1.printStackTrace();
            return false;
        }
        try {
            //2.获取链接
            URLConnection conn = url.openConnection();
            //3.输入流
            InputStream inStream = conn.getInputStream();
            //3.写入文件
            FileOutputStream fs = new FileOutputStream(saveFile);
            byte[] buffer = new byte[1024];
            while ((byteRead = inStream.read(buffer)) != -1) {
                fs.write(buffer, 0, byteRead);
            }
            inStream.close();
            fs.close();
            return true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }







    /**
     * 校验微信token
     * @description: sha1
     * @author: lvyq
     * @date: 2022/7/8 15:18
     * @version 1.0
     */

    public static String sha1(String data) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA1");
        //把字符串转为字节数组
        byte[] b = data.getBytes();
        //使用指定的字节来更新我们的摘要
        md.update(b);
        //获取密文  （完成摘要计算）
        byte[] b2 = md.digest();
        //获取计算的长度
        int len = b2.length;
        //16进制字符串
        String str = "0123456789abcdef";
        //把字符串转为字符串数组
        char[] ch = str.toCharArray();
        //创建一个40位长度的字节数组
        char[] chs = new char[len*2];
        //循环20次
        for(int i=0,k=0;i<len;i++) {
            //获取摘要计算后的字节数组中的每个字节
            byte b3 = b2[i];
            // >>>:无符号右移
            // &:按位与
            //0xf:0-15的数字
            chs[k++] = ch[b3 >>> 4 & 0xf];
            chs[k++] = ch[b3 & 0xf];
        }
        //字符数组转为字符串
        return new String(chs);
    }


    /**
     * 解析base64的二维码内容
     * @param baseStr
     * @return
     */
//    public static String deEncodeByBase64(String baseStr) {
//        String content = null;
//        BufferedImage image;
//        BASE64Decoder decoder = new BASE64Decoder();
//        byte[] b=null;
//        try {
//            int i = baseStr.indexOf("data:image/png;base64,");
//            baseStr = baseStr.substring(i+"data:image/png;base64,".length());//去掉base64图片的data:image/png;base64,部分才能转换为byte[]
//
//            b = decoder.decodeBuffer(baseStr);//baseStr转byte[]
//            ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(b);//byte[] 转BufferedImage
//            image = ImageIO.read(byteArrayInputStream);
//            LuminanceSource source = new BufferedImageLuminanceSource(image);
//            Binarizer binarizer = new HybridBinarizer(source);
//            BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
//            Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
//            hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
//            Result result = new MultiFormatReader().decode(binaryBitmap, hints);//解码
//            System.out.println("图片中内容：  ");
//            System.out.println("content： " + result.getText());
//            content = result.getText();
//        } catch (IOException e) {
//            e.printStackTrace();
//        } catch (NotFoundException e) {
//            e.printStackTrace();
//        }
//        return content;
//    }


    /**
     * 获取当前时间开始和结束小时
     * */
    public static String getStartEndHour() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MINUTE, 0);       // 清空分
        calendar.set(Calendar.SECOND, 0);       // 清空秒
        calendar.set(Calendar.MILLISECOND, 0);  // 清空毫秒
        calendar.add(Calendar.HOUR, 0); //清空小时

        String startTime = "";
        String endTime = "";
        startTime = dateFormat.format(calendar.getTime()); //获取开始时间
        calendar.add(Calendar.HOUR, 1); 		// 添加1小时
        Date nextHour = calendar.getTime();
        endTime = dateFormat.format(nextHour);  //获取结束时间
        return startTime + "~" + endTime;
    }


    public static boolean isNumeric(String str) {
        try {
            Double.parseDouble(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }


    /**
     * 获取视频号cookies
     * @param cookies
     * @return
     */
    public static String getChannelsCookie(String cookies) {
        JSONArray jsonArray =  JSONArray.parseArray(cookies);
        String cookieRes = "";
        for(int i =0;i < jsonArray.size();i++){
            JSONObject cook =  (JSONObject)jsonArray.get(i);
            if(cook.getString("name").equals("sessionid")){
                cookieRes = cook.getString("value");
            }
        }
        return "sessionid=" + cookieRes;
    }


}
